/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function validUsername(str) {
  const valid_map = ['admin', 'editor']
  return valid_map.indexOf(str.trim()) >= 0
}

/**
 * @param {string} url
 * @returns {Boolean}
 */
export function validURL(url) {
  const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
  return reg.test(url)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function validLowerCase(str) {
  const reg = /^[a-z]+$/
  return reg.test(str)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function validUpperCase(str) {
  const reg = /^[A-Z]+$/
  return reg.test(str)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function validAlphabets(str) {
  const reg = /^[A-Za-z]+$/
  return reg.test(str)
}

/**
 * @param {string} mobile
 * @returns {Boolean}
 */
export function validMobile(mobile) {
  const reg = /^(13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])\d{8}$/
  return reg.test(mobile)
}

/**
 * @param {string} email
 * @returns {Boolean}
 */
export function validEmail(email) {
  const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
  return reg.test(email)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function isString(str) {
  if (typeof str === 'string' || str instanceof String) {
    return true
  }
  return false
}

/**
 * @param {Array} arg
 * @returns {Boolean}
 */
export function isArray(arg) {
  if (typeof Array.isArray === 'undefined') {
    return Object.prototype.toString.call(arg) === '[object Array]'
  }
  return Array.isArray(arg)
}

/**
 * 如果是 undefined， null， ''， NaN，[]，{} ，都返回true，否则返回false
 * @param {object} value
 * @returns {Boolean}
 */
export function isEmpty(value) {
  switch (typeof value) {
    case 'undefined':
      return true

    case 'object':
      if (value === null || value.length === 0) return true
      for (var i in value) {
        return false
      }
      return true

    case 'number':
      return isNaN(value)

    case 'boolean':
      return value !== true && value !== false

    case 'string':
      return value === '' || value.length === 0
  }

  return false
}

/**
 * 如果不是 undefined， null， ''， NaN，[]，{} ，都返回true，否则返回false
 * @param {object} value
 * @returns {Boolean}
 */
export function notEmpty(value) {
  return !isEmpty(value)
}

/**
 * 如果是 空白字符串 返回true，否则返回false
 * @param {string} value
 * @returns {Boolean}
 */
export function isBlank(str) {
  return (str + '').replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length === 0
}

/**
 * 检查时间是否解析是否失败（Invalid Date）
 * @param {Date} date
 * @returns {Boolean}
 */
export function isValidDate(date) {
  return date instanceof Date && !isNaN(date.getTime())
}

/**
 * 验证工具类
 */
var validate = {
  v: '1.0.0'

  /**
   * @param {string} path
   * @returns {Boolean}
   */
  , isExternal: function(path) {
    return /^(https?:|mailto:|tel:)/.test(path)
  }

  /**
   * @param {string} url
   * @returns {Boolean}
   */
  , validURL: function(url) {
    const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
    return reg.test(url)
  }

  /**
   * @param {string} str
   * @returns {Boolean}
   */
  , validLowerCase: function(str) {
    const reg = /^[a-z]+$/
    return reg.test(str)
  }

  /**
   * @param {string} str
   * @returns {Boolean}
   */
  , validUpperCase: function(str) {
    const reg = /^[A-Z]+$/
    return reg.test(str)
  }

  /**
   * @param {string} str
   * @returns {Boolean}
   */
  , validAlphabets: function(str) {
    const reg = /^[A-Za-z]+$/
    return reg.test(str)
  }

  /**
   * @param {string} mobile
   * @returns {Boolean}
   */
  , validMobile: function(mobile) {
    const reg = /^(13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])\d{8}$/
    return reg.test(mobile)
  }

  /**
   * @param {string} email
   * @returns {Boolean}
   */
  , validEmail: function(email) {
    const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
    return reg.test(email)
  }

  /**
   * @param {string} str
   * @returns {Boolean}
   */
  , isString: function(str) {
    if (typeof str === 'string' || str instanceof String) {
      return true
    }
    return false
  }

  /**
   * @param {Array} arg
   * @returns {Boolean}
   */
  , isArray: function(arg) {
    if (typeof Array.isArray === 'undefined') {
      return Object.prototype.toString.call(arg) === '[object Array]'
    }
    return Array.isArray(arg)
  }

  /**
   * 如果是 undefined， null， ''， NaN，[]，{} ，都返回true，否则返回false
   * @param {object} value
   * @returns {Boolean}
   */
  , isEmpty: function(value) {
    switch (typeof value) {
      case 'undefined':
        return true

      case 'object':
        if (value === null || value.length === 0) return true
        for (var i in value) {
          return false
        }
        return true

      case 'number':
        return isNaN(value)

      case 'boolean':
        return value !== true && value !== false

      case 'string':
        return value === '' || value.length === 0
    }

    return false
  }

  /**
   * 如果不是 undefined， null， ''， NaN，[]，{} ，都返回true，否则返回false
   * @param {object} value
   * @returns {Boolean}
   */
  , notEmpty: function(value) {
    return !this.isEmpty(value)
  }

  /**
   * 如果是 空白字符串 返回true，否则返回false
   * @param {string} value
   * @returns {Boolean}
   */
  , isBlank: function(str) {
    return (str + '').replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length === 0
  }

  /**
   * 如果不是 空白字符串 返回true，否则返回false
   * @param {string} value
   * @returns {Boolean}
   */
  , notBlank: function(str) {
    return !this.isBlank(str)
  }

  /**
   * 检查时间是否解析是否失败（Invalid Date）
   * @param {Date} date
   * @returns {Boolean}
   */
  , isDate: function(date) {
    return date instanceof Date && !isNaN(date.getTime())
  }

  /**
   * 判断是否为整数（并验证数据范围）
   * @param {string} integer
   * @returns {Boolean}
   */
  , validInteger: function(integer) {
    return this.validIntNum(integer) && integer > 2147483647 && integer < -2147483648
  }

  /**
   * 判断是否为整数
   * @param {string} integer
   * @returns {Boolean}
   */
  , validIntNum: function(integer) {
    const reg = /^-?[1-9]\d*$/
    return reg.test(integer)
  }

  /**
   * 判断是否为数字
   * @param {string} number
   * @returns {Boolean}
   */
  , validNumber: function(number) {
    const reg = /^(\-|\+)?\d+(\.\d+)?$/
    return reg.test(number)
  }

  /**
   * 判断是否为布尔值
   * @param {string} bool
   * @returns {Boolean}
   */
  , validBoolean: function(bool) {
    return /^(t|f|y|n|true|false|yes|no|1|0)$/i.test(bool)
  }

  /**
   * 判断是否为布尔值真
   * @param {string} bool
   * @returns {Boolean}
   */
  , validBoolTrue: function(bool) {
    return /^(t|y|true|yes|1)$/i.test(bool)
  }

  /**
   * 判断是否为JSON字符串
   * @param {string} val
   * @returns {Boolean}
   */
  , isJson: function(val) {
    if (typeof val === 'string') {
      try {
        JSON.parse(val)
        return true
      } catch (e) {
        return false
      }
    }
    return false
  }
}

export default validate
